﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;

namespace Framework.ContentWorkflow
{
    public class CMSApproveService:ICMSApproveService
    {
        #region Excute Action

        public void Excute(CMSActionContext actionContext)
        {
            using (TransactionScope scope = new TransactionScope())
            {
                // Open Object Context Connection in the scope using
                List<ICMSActionHandler> handlers = this.GetActionHandler(actionContext.Request.ActionName,actionContext.Request.ContentType).OrderBy(d => d.Order).ToList(); // Get according to the request content type and action type 
                var enumerator = handlers.GetEnumerator();
                Func<ICMSActionHandler> getNextHandler = () =>
                {
                    if (enumerator.MoveNext())
                    {
                        return enumerator.Current;
                    }
                    return null;
                };
             

                try
                {
                    ExcuteActionHandler(getNextHandler(), actionContext, getNextHandler);

                    //Do some things after all action handlers have been excuted.
                    if (actionContext.Request.IsValid && !actionContext.Request.Canceled)
                    {
                        actionContext.Request.Action();

                        //Excute a publish action events 
                        CMSEventsAggregator.Current.Publish<CMSActionContext>(this, new CMSEventArgs<CMSActionContext>() { Value = actionContext }); 
                    }
                }
                catch (Exception e)
                {
                }
                scope.Complete();
            } 
        }

        internal void ExcuteActionHandler(ICMSActionHandler handler, CMSActionContext context,Func<ICMSActionHandler> getNext)
        {
            if (!context.Request.Canceled && context.Request.IsValid)
            {
                handler.Validate(context);
                var next = getNext();
                if (next != null)
                {
                    ExcuteActionHandler(next, context, getNext);
                }
                else
                {
                    // Do some action after the last validation has been excuted.
                }
                handler.Handle(context);
            }
            else
            {
                throw new InvalidOperationException("Context has handled with Error!");
            }
        }

        public void Excute()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region Get Action Handler List

        protected List<ICMSActionHandler> GetActionHandler(string actionName, string contentType)
        {
            return new List<ICMSActionHandler>();
        }

        #endregion

    }
}
